﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ymatou.CommonService;
using Ymatou.User.Common.UserEnum.Auth;
using Ymatou.User.Dto.Auth;
using Ymatou.User.ServerResponse;
using Ymatou.UserAuth.Agent.Login;
using Ymatou.UserAuth.Agent.Sso;
using Ymatou.UserAuth.RestfullCliet;
using Ymatou.UserAuth.Utility;

namespace Ymatou.UserAuth.Agent.Token
{
    public class UserTokenAgent : IUserTokenAgent
    {
        public void RemoveToken(string token)
        {
            if (string.IsNullOrEmpty(token)) return;
            YmtRestWebClient.Instance.Post<SSOTokenDto>(new SSOTokenDto
            {
                Token = token
            }, errorHandle: err => ApplicationLog.Error("移除token错误", err));
        }
       
        public string CreateUserTokenByUserId(int userId)
        {
            var result = YmtRestWebClient.Instance.Post<ResponseData<string>, UserTokenDto>(new UserTokenDto { UserId = userId }
                , defReturn: ResponseData<string>.CreateFail(string.Empty, lastErrorMessage: "生成token错误")
                , errorHandle: err => ApplicationLog.Error(string.Format("根据用户userId {0} 生成token错误", userId), err));
            return result.Success ? result.Result : string.Empty;
        }

        public void CreateUserTokenAndWriteSSOCookie(int userId)
        {
            var result = CreateUserTokenByUserId(userId);
            if (!string.IsNullOrEmpty(result))
            {
                SSOClient.SetUserTokenCookie(result);
            }
        }

        /// <summary>
        /// token 认证
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public ResponseData<TokenResponseDto> RequestTokenAuth(string token)
        {
            var result = YmtRestWebClient.Instance.Get<ResponseData<TokenResponseDto>, SignAuthRequestDto>(new SignAuthRequestDto
            {
                Token = token
            }
            , defReturn: ResponseData<TokenResponseDto>.CreateFail(new TokenResponseDto { Code = LoginResponseCode.SystemInnerError, UserData = new UserTokenData { UserId = -1 } }, lastErrorMessage: "验证token错误")
            , errorHandle: err => ApplicationLog.Error("请求 token 认证错误", err));
            return result;
        }


        /// <summary>
        /// VerifyUserCookieToken
        /// </summary>    
        public void VerifyUserSSOCookieToken(bool redirectLoginPage, bool redirectOpenAuht = true)
        {           
            SSOClient.CheckSign(
                                token => RequestTokenAuth(token)
                                , (originalVal, sign) => CheckSign(originalVal, sign).Success
                                , userId =>
                                {
                                    new UserLoginAuthAgent().GetBuserBills(userId);
                                }
                                , redirectLoginPage
                                , redirectOpenAuht
                                );
        }

        /// <summary>
        ///  验证用户cookie （SSO）。 
        /// </summary>
        /// <param name="redirectLoginPage">是否允许重定向到登陆页</param>    
        /// <param name="failAction">验证失败执行操作</param>
        /// <param name="successAction">验证成功执行操作</param>
        /// <param name="redirectOpenAuht">是否允许定向到OpenAuth站点</param>
        public void VerifyUserSSOCookieToken(bool redirectLoginPage, Action failAction, Action<int> successAction, bool redirectOpenAuht = true)
        {            
            SSOClient.CheckSign(
                               token => RequestTokenAuth(token)
                               , (originalVal, sign) => CheckSign(originalVal, sign).Success
                               , userId =>
                               {
                                   successAction(userId);
                               }
                               , redirectLoginPage
                               , redirectOpenAuht
                               , failAction);
        }

        /// <summary>
        /// CheckSign
        /// </summary>             
        public ResponseData<SignAuthResponseDto2> CheckSign(string originalVal, string sign)
        {
            //TODO:校验token
            var signResult = YmtRestWebClient.Instance.Post<ResponseData<SignAuthResponseDto2>, SignAuthRequestDto>(new SignAuthRequestDto
            {
                Sign = sign,
                OriginalVal = originalVal,
            }
           , defReturn: ResponseData<SignAuthResponseDto2>.CreateFail(new SignAuthResponseDto2 { Code = LoginResponseCode.SystemInnerError }, lastErrorMessage: "请求认证错误！")
           , errorHandle: err =>
           {
               ApplicationLog.Error("请求认证签名错误", err);
           });
            ApplicationLog.Debug(string.Format("{0} 签名认证返回 {1} {2}", sign, signResult.Success, signResult.LastErrorMessage));
            return signResult;
        }
        /// <summary>
        /// CheckSign
        /// </summary> 
        public ResponseData<SignAuthResponseDto2> CheckSign(string token, int userId)
        {
            AuthAssert.AssertStringNotNull(token, "token 不能为空");
            AuthAssert.Assert(() => userId > 0, "错误的用户ID");

            var sign = new SignInfo(token, userId);
            sign.GenerateSign();
            return this.CheckSign(sign.OriginalVal, sign.Sign);
        }
    }
}
